Computing systems and associated networks have greatly revolutionized our world. Computing systems operate via the use of software, which includes instructions that instruct the hardware of a computing system to operate in particular ways. Software is often initially drafted using source code that has semantics that are more recognizable and readable to a trained human coder. A software “build” involves the construction of an observable and tangible result using the source code. For instance, the result of a software build might include standalone software artifacts that can be run on a computer, or might include software in an interpreted language.
Modern computer programs may be quite large, often involving more than a million lines of code and thousands of executable components (e.g., components, functions, objects, and the like). Build systems are often used in such large-scale software development projects. The build systems perform such tasks as managing the process of building source code, applying static analyzers, and executing tests.
Conventional build systems view a software project as a group of inter-dependent components and inherently perform regression test selection at the component level. The inter-dependent components including both working components and test components. The working components represent the actual program under development. The test components are used to ensure that the program still performs as expected at each stage of development. For instance, given a change in the working components, the build system uses a build dependency graph to identify test components that are impacted by the change and perform activities only using those test components. More specifically, whenever any dependency of a test component is impacted by the given change that is subjected to a build, all tests in that test component are executed. Otherwise, the test component is skipped and thus no tests in the test component are executed. This type of testing is often referred to as “module-level regression testing” (also called herein “component-level regression testing”).
A major advantage of component-level regression testing is that this testing does not require any additional metadata beyond what was used to build in the first place. There are conventional build systems that keep metadata that define fine-grained dependencies like exercised statements for each test. This allows fewer tests to be performed because only those tests that impact the corresponding changed statement in a working component would be run—as opposed to running all tests that impact the entire changed component. However, for large software projects, storage and maintenance of this additional metadata adds non-trivial processing and storage overhead.
The subject matter claimed herein is not limited to embodiments that solve any disadvantages or that operate only in environments such as those described above. Rather, this background is only provided to illustrate one exemplary technology area where some embodiments described herein may be practiced.